#include <stdio.h>
#include <stdbool.h>

//290. 单词规律
//给定一种规律 pattern 和一个字符串 s ，判断 s 是否遵循相同的规律。
//这里的 遵循 指完全匹配，例如， pattern 里的每个字母和字符串 s 中的每个非空单词之间存在着双向连接的对应规律。
#define MAX_LEN 100
#define MAX_NUM 1000
#define KEY_NUM 2

struct HashTable {
    char key[KEY_NUM];
    char value[MAX_LEN];
    UT_hash_handle hh;
};

struct HashTable *g_user;

/* 往哈希表添加元素 */
bool addUser(char *character, char *value)
{
    struct HashTable *cur = NULL;
    struct HashTable *next = NULL;
    HASH_ITER(hh, g_user, cur, next) {    // 不同的键应该对于不同的值，如果值相同，则不符合条件
        if (strcmp(cur->value, value) == 0) {
            return false;
        }
    }

    struct HashTable *tmp = (struct HashTable *)malloc(sizeof(struct HashTable));
    if (tmp != NULL) {
        memset(tmp->key, 0, sizeof(char) * KEY_NUM);
        memset(tmp->value, 0, sizeof(char) * MAX_LEN);
        strcpy(tmp->key, character);
        strcpy(tmp->value, value);
        HASH_ADD_STR(g_user, key, tmp);
        return true;
    }

    return false;
}

bool wordPattern(char *pattern, char *s)
{
    g_user = NULL;

    char **tmp = (char **)malloc(sizeof(char *) * MAX_NUM);
    if (tmp == NULL) {
        return false;
    }
    int wordNum = 0;
    char *ptr = NULL;
    ptr = strtok(s, " ");    // 获取各个单词
    while (ptr != NULL) {
        tmp[wordNum] = (char *)malloc(sizeof(char) * MAX_LEN);
        if (tmp[wordNum] == NULL) {
            return false;
        }
        strcpy(tmp[wordNum], ptr);
        wordNum++;
        ptr = strtok(NULL, " ");
    }

    int len = strlen(pattern);
    if (len != wordNum) {
        return false;
    }

    int i;
    for (i = 0; i < len; i++) {
        struct HashTable *ptr = NULL;
        char ele[KEY_NUM] = {0};
        ele[0] = pattern[i];
        int cnt = HASH_COUNT(g_user);
        HASH_FIND_STR(g_user, ele, ptr);
        if (ptr != NULL) {
            if (strcmp(ptr->value, tmp[i]) != 0) {
                return false;
            }
        } else {
            if (!addUser(ele, tmp[i])) {
                return false;
            }
        }
    }

    return true;
}